package com.ccteam.fluidmusic.ui.moment.comment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.ConcatAdapter
import com.bumptech.glide.Glide
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.CommentListInnerCommentItemBinding
import com.ccteam.fluidmusic.databinding.CommentListParentCommentItemBinding
import com.ccteam.fluidmusic.databinding.DialogReplayListBinding
import com.ccteam.fluidmusic.view.adapters.ViewBindViewHolder
import com.ccteam.fluidmusic.view.adapters.comment.CommentItemCallback
import com.ccteam.fluidmusic.view.adapters.comment.ReplayItemCallback
import com.ccteam.fluidmusic.view.adapters.paging.CustomLoadStateAdapter
import com.ccteam.fluidmusic.view.adapters.paging.PagingAdapter
import com.ccteam.fluidmusic.view.adapters.viewbinding.ViewBindingAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.fluidmusic.view.bean.PublishCommentData
import com.ccteam.model.moment.comment.COMMENT_TYPE_REPLAY
import com.ccteam.model.moment.comment.COMMENT_TYPE_REPLAY_REPLAY
import com.ccteam.shared.result.moment.comment.MomentCommentItem
import com.ccteam.shared.result.moment.comment.MomentReplayItem
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/3/25
 *
 * 查看该评论所有回复的Fragment
 */
@AndroidEntryPoint
class ReplayListFragment: BottomSheetDialogFragment()  {

    private var _binding: DialogReplayListBinding? = null
    private val binding get() = _binding!!

    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    private val commentsViewModel by viewModels<CommentsViewModel>()

    private lateinit var dataAdapter: ReplayListRVAdapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = DialogReplayListBinding.inflate(inflater,container,false)
        return binding.root
    }

    /**
     * 在start方法中
     * 我们根据屏幕高度重新设置弹窗的高度
     */
    override fun onStart() {
        super.onStart()

        val layoutParams = binding.root.layoutParams
        layoutParams.height = getPeekHeight()
        binding.root.layoutParams = layoutParams
        (dialog as? BottomSheetDialog)?.behavior?.apply {
            skipCollapsed = true
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val parentCommentAdapter = ParentCommentRVAdapter(commentCallback)
        dataAdapter = ReplayListRVAdapter(replayCallback)

        lightBounceEdgeEffectFactory.applyBounceView(binding.rvComments,this)
        binding.rvComments.edgeEffectFactory = lightBounceEdgeEffectFactory

        binding.rvComments.adapter = ConcatAdapter(parentCommentAdapter,dataAdapter.withLoadStateFooter(
            CustomLoadStateAdapter(dataAdapter,true){
                dataAdapter.retry()
            }
        ))

        commentsViewModel.loadMessage.observe(viewLifecycleOwner, {
            binding.statusView.changeToLoadingStatus(it is LoadMessage.Loading)
            binding.statusView.changeToErrorStatus(it)
        })

        viewLifecycleOwner.lifecycleScope.launch {
            commentsViewModel.commentList.collectLatest {
                dataAdapter.submitData(it)
            }
        }

        viewLifecycleOwner.lifecycleScope.launch {
            dataAdapter.loadStateFlow.collectLatest { state ->
                commentsViewModel.setLoadMessage(state.refresh)
            }
        }

        commentsViewModel.parentCommentList.observe(viewLifecycleOwner, {
            parentCommentAdapter.submitList(it)
        })

        binding.statusView.setRetryClickListener {
            dataAdapter.refresh()
            commentsViewModel.refreshParentCommentInfo()
        }

    }

    override fun onResume() {
        super.onResume()

        setFragmentResultListener(PublishCommentFragment.REFRESH_COMMENT_RESULT){ _, bundle ->
            if(bundle.getBoolean(PublishCommentFragment.REFRESH_COMMENT_RESULT)){
                dataAdapter.refresh()
            }
        }
    }

    private val replayCallback = object: ReplayItemCallback {

        override fun replayItemClicked(view: View, item: MomentReplayItem) {
            findNavController().navigate(
                ReplayListFragmentDirections.actionCommentsFragmentToPublishCommentFragment(
                    PublishCommentData(
                        item.momentId,
                        COMMENT_TYPE_REPLAY_REPLAY,
                        item.userId,
                        item.userName,
                        item.commentId
                    )
                )
            )
        }

    }

    private val commentCallback = object: CommentItemCallback{
        override fun commentItemClicked(view: View, item: MomentCommentItem) {
            findNavController().navigate(
                ReplayListFragmentDirections.actionCommentsFragmentToPublishCommentFragment(
                    PublishCommentData(
                        item.momentId, COMMENT_TYPE_REPLAY, item.userId, item.userName, item.id
                    )
                )
            )
        }

    }

    class ParentCommentRVAdapter(
        private val commentCallback: CommentItemCallback
    ): ViewBindingAdapter<CommentListParentCommentItemBinding, ParentCommentRVAdapter.ParentCommentViewHolder,MomentCommentItem>(
        MomentCommentItem.differCallback
    ){

        override fun createViewBinding(parent: ViewGroup, viewType: Int): ParentCommentViewHolder {
            return ParentCommentViewHolder(
                CommentListParentCommentItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
            )
        }

        override fun bindItem(
            holder: ParentCommentViewHolder,
            position: Int,
            item: MomentCommentItem,
            payloads: MutableList<Any>
        ) {
            handleMomentParentComment(holder,item)
        }

        private fun handleMomentParentComment(holder: ParentCommentViewHolder, item: MomentCommentItem?){
            item?.let {
                holder.item = it
                holder.binding.tvMomentParentCommentContent.text = item.commentContent
                holder.binding.tvCommentDatetime.text = item.publishTime
                holder.binding.tvMomentParentCommentAccountName.text = item.userName
                Glide.with(holder.binding.ivMomentParentCommentHeadImg)
                    .load(item.userPhotoUrl)
                    .placeholder(R.drawable.img_default_artist_small)
                    .into(holder.binding.ivMomentParentCommentHeadImg)
            }
        }

        inner class ParentCommentViewHolder(binding: CommentListParentCommentItemBinding) :
            ViewBindViewHolder<CommentListParentCommentItemBinding>(binding){
            var item: MomentCommentItem? = null

            init {
                binding.root.setOnClickListener {
                    item?.let { data ->
                        commentCallback.commentItemClicked(it,data)
                    }
                }
            }
        }
    }

    class ReplayListRVAdapter(
        private val callback: ReplayItemCallback
    ): PagingAdapter<MomentReplayItem, ReplayListRVAdapter.ReplayCommentViewHolder,CommentListInnerCommentItemBinding>(MomentReplayItem.differCallback){

        override fun createPagingViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): ReplayCommentViewHolder {
            return ReplayCommentViewHolder(
                CommentListInnerCommentItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
            )
        }

        override fun bindPagingItem(
            holder: ReplayCommentViewHolder,
            position: Int,
            item: MomentReplayItem?,
            payloads: MutableList<Any>
        ) {
            handleComments(holder,item)
        }

        private fun handleComments(holder: ReplayCommentViewHolder, item: MomentReplayItem?){
            item?.let {
                holder.item = it
                holder.binding.tvMomentInnerCommentAccountName.text = it.userName
                holder.binding.tvMomentInnerCommentContent.text = it.commentContent
                holder.binding.tvInnerCommentDatetime.text = it.publishTime
                Glide.with(holder.binding.ivMomentInnerCommentHeadImg)
                    .load(it.userPhotoUrl)
                    .placeholder(R.drawable.img_default_artist_small)
                    .into(holder.binding.ivMomentInnerCommentHeadImg)
            }
        }

        inner class ReplayCommentViewHolder(
            binding: CommentListInnerCommentItemBinding
        ): ViewBindViewHolder<CommentListInnerCommentItemBinding>(binding){
            var item: MomentReplayItem? = null

            init {
                binding.root.setOnClickListener {
                    item?.let { data ->
                        callback.replayItemClicked(it,data)
                    }

                }
            }
        }
    }

    /**
     * 返回屏幕高度
     */
    private fun getPeekHeight(): Int{
        return resources.displayMetrics.heightPixels
    }

    override fun onDestroyView() {
        super.onDestroyView()

        _binding = null
    }
}